package com.instalinks.android.apps.helper;

import java.util.Hashtable;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;

import com.instalinks.android.apps.HomeActivity;
import com.instalinks.android.apps.R;
import com.instalinks.android.apps.service.AppService;
import com.instalinks.android.lib.AppHelper;
import com.instalinks.android.lib.ApplicationNotifications;
import com.instalinks.android.lib.Config;
import com.instalinks.android.lib.PhoneAttributes;
import com.instalinks.android.lib.UrlData;
import com.instalinks.android.lib.UrlResponse;
import com.instalinks.android.lib.UrlResponse.UrlResponseType;
import com.instalinks.android.lib.enums.DeviceType;
import com.instalinks.android.lib.enums.NetworkType;
import com.instalinks.android.lib.enums.PhoneParams;
import com.instalinks.android.lib.enums.ServiceStartStatus;

public class AppConfig extends Config {

	private PhoneAttributes mPhoneAttr;

	public AppConfig(Context context) {
		super(context, Constants.CONFIG_FILE_NAME, false);

		this.rePopulate();
	}

	public String getAppUrl() throws Exception {
		try {
			UrlData urlData = new UrlData(Constants.APP_CONFIG_URL, 25000);

			Hashtable<String, String> htParams = new Hashtable<String, String>();

			htParams.put(ConfigParams.appid.toString(),
					this.mContext.getPackageName());

			UrlResponse response = urlData.postData(htParams);

			if (response.getResponseType() == UrlResponseType.success) {
				String url = response.getMessage();
				url = url.replace("\n", "");
				try {
					this.setDataPostUrl(url);
				} catch (Exception e) {
				}
				return url;// response.getMessage();
			} else {
				throw new Exception(
						"Error getting application data post url. Try reopening the application");
			}
		} catch (Exception e) {
			throw e;
		}
	}
	
	public ApplicationNotifications getServiceNotificationInstance(boolean allowSound){
		ApplicationNotifications appNotif = new ApplicationNotifications(mContext, Constants.SERVICE_NOTIFICATION_ID, Constants.NOTIFICATION_TITLE, 
				isServiceRunning()?R.drawable.service_enable:R.drawable.service_disable, allowSound, false, HomeActivity.class.getName());
		
		return  appNotif;
	}

	public ApplicationNotifications getExternalNotificationInstance(boolean allowSound){
		ApplicationNotifications appNotif = new ApplicationNotifications(mContext, Constants.EXTERNAL_NOTIFICATION_ID, Constants.NOTIFICATION_TITLE, 
				R.drawable.external_notification, allowSound, true);
		
		return  appNotif;
	}
	
	public void notifyServiceState(){
		notifyServiceState(isServiceRunning());
	}
	
	public void notifyServiceState(boolean enabled){
		if(enabled){
			getServiceNotificationInstance(false).notify("Service Enabled", HomeActivity.class.getName());
		}else{
			getServiceNotificationInstance(false).notify("Service Disabled", HomeActivity.class.getName());
		}
	}
	
	public boolean isAppUpToDate() {
		return true;
	}

	public void registerForC2dm(boolean force) {

		if (force)
			AppHelper.registerForC2dm(mContext, Constants.C2DM_EMAIL);
		else {
			if (this.isConfigExists()) {
				if (this.getRegistrationId() == null
						|| this.getRegistrationId().trim().length() < 10) {

					AppHelper.registerForC2dm(mContext, Constants.C2DM_EMAIL);
				}
			}
		}
	}

	public void unregisterForC2dm() {

		AppHelper.unregisterForC2dm(mContext);
	}

	public Hashtable<String, String> getDataPostHashtable() {
		Hashtable<String, String> htParams = new Hashtable<String, String>();

		htParams.put(PhoneParams.subid.toString(), getSubscriberId());
		htParams.put(PhoneParams.deviceid.toString(), getDeviceId());
		htParams.put(PhoneParams.email.toString(), getEmail());

		return htParams;
	}

	public boolean activateDevice() {
		try {
			UrlData urlData = new UrlData(this.getDataPostUrl(), 25000);

			Hashtable<String, String> htParams = getDataPostHashtable();

			htParams.put(ConfigParams.mode.toString(),
					ConfigParams.modes.activate.toString());

			UrlResponse response = urlData.postData(htParams);

			if (response.getResponseType() == UrlResponseType.success) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public boolean sendDataMessage(ConfigParams.modes mode, String sendAs,
			String sendTo, String message) {
		try {
			UrlData urlData = new UrlData(this.getDataPostUrl(), 25000);

			Hashtable<String, String> htParams = getDataPostHashtable();

			htParams.put(ConfigParams.mode.toString(), mode.toString());
			htParams.put(ConfigParams.field1.toString(), message);
			htParams.put(ConfigParams.field2.toString(), sendTo);
			htParams.put(PhoneParams.sender.toString(), sendAs);

			UrlResponse response = urlData.postData(htParams);

			if (response.getResponseType() == UrlResponseType.success) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public boolean sendRegistrationIdToHost(String registrationId) {
		try {
			UrlData urlData = new UrlData(getDataPostUrl());

			Hashtable<String, String> htParams = getDataPostHashtable();

			htParams.put(ConfigParams.mode.toString(),
					ConfigParams.modes.c2dm.toString());

			htParams.put(ConfigParams.registrationid.toString(), registrationId);

			UrlResponse response = urlData.postData(htParams);

			if (response.getResponseType() == UrlResponseType.success) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public final boolean isServiceRunning() {
		ActivityManager manager = (ActivityManager) mContext
				.getSystemService(Context.ACTIVITY_SERVICE);
		for (RunningServiceInfo srv : manager
				.getRunningServices(Integer.MAX_VALUE)) {
			if (srv.service.getClassName().equals(AppService.class.getName())) {
				return true;
			}
		}
		return false;
	}

	public void rePopulate() {
		super.rePopulate();

		getPhoneAttributesInstance().resetAllAttributes();
	}

	private PhoneAttributes getPhoneAttributesInstance() {
		if (mPhoneAttr == null)
			mPhoneAttr = new PhoneAttributes(mContext);
		return mPhoneAttr;
	}

	public ServiceStartStatus allGoodToRunService() {

		if (!isAppUpToDate())
			return ServiceStartStatus.NewUpdateAvailable;
		else if (!isValidDataNetwork())
			return ServiceStartStatus.ConnectivityFailure;
		else
			return ServiceStartStatus.Ok;
	}

	public void handleServiceResponse(ServiceStartStatus status) {
		switch (status) {
		case ConnectivityFailure:
			AppHelper.alert(mContext, mContext.getString(R.string.network_error));
			break;
		case NewUpdateAvailable:
			checkUpdates();
			break;
		case Started:
		case Ok:
			break;
		}
	}

	public void checkUpdates() {
		if (isAppUpToDate()) {
			AppHelper.alert(mContext, "Application is up-to-date");
		} else {
			questionForUpate();
		}
	}

	private final void questionForUpate() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this.mContext);

		builder.setTitle("App Update")
				.setMessage("New version of app is available for download.")
				// .setIcon(R.drawable.icon)
				.setPositiveButton("ok", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						getUpdate();
					}
				})
				.setNegativeButton("Cancel",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {

							}
						}).setCancelable(true);

		builder.show();
	}

	private final void getUpdate() {
		AppHelper.launchMarketUrl(mContext, mContext.getPackageName());
	}

	// /////////////////////////////////////////////////////////////////////
	public boolean isActivatedFlag() {
		return getBooleanValue(ConfigParams.activated.toString());
	}

	public void setActivatedFlag(boolean visible) throws Exception {
		setBooleanValue(ConfigParams.activated.toString(), visible);
	}

	// *************************
	public String getDataPostUrl() {
		return getValue(ConfigParams.app_url.toString());
	}

	public void setDataPostUrl(String url) throws Exception {
		setValue(ConfigParams.app_url.toString(), url);
	}

	// *************************
	public String getVersion() {
		return getValue(ConfigParams.version.toString());
	}

	public void setVersion(String version) throws Exception {
		setValue(ConfigParams.version.toString(), version);
	}

	// *************************
	public String getRegistrationId() {
		return getValue(ConfigParams.registrationid.toString());
	}

	public void setRegistrationId(String value) throws Exception {
		setValue(ConfigParams.registrationid.toString(), value);
	}

	// *************************
	public String getEmail() {
		return getPhoneAttributesInstance().primaryEmail;
	}

	public String getDeviceId() {
		return getPhoneAttributesInstance().deviceId;
	}

	public String getSubscriberId() {
		return getPhoneAttributesInstance().subscriberId;
	}

	public String getLocation() {
		return getPhoneAttributesInstance().location;
	}

	public String getBatteryStatus() {
		return getPhoneAttributesInstance().batteryStatus;
	}

	public String getSignalStrength() {
		return getPhoneAttributesInstance().signalStrength;
	}

	public boolean isConnectedToNetwork() {
		return getPhoneAttributesInstance().isConnected;
	}

	public NetworkType getNetworkType() {
		return getPhoneAttributesInstance().networkType;
	}

	public boolean isWifiNetwork() {
		return (getPhoneAttributesInstance().networkType == NetworkType.WiFi);
	}

	public boolean is3GNetwork() {
		return (getPhoneAttributesInstance().networkType == NetworkType.HSDPA || getPhoneAttributesInstance().networkType == NetworkType.UMTS);
	}

	public boolean is2GNetwork() {
		return (getPhoneAttributesInstance().networkType == NetworkType.GPRS || getPhoneAttributesInstance().networkType == NetworkType.EDGE);
	}

	public boolean isGSMDevice() {
		return (getPhoneAttributesInstance().deviceType == DeviceType.GSM);
	}

	public boolean isCDMADevice() {
		return (getPhoneAttributesInstance().deviceType == DeviceType.CDMA);
	}

	public String getDeviceType() {
		return getPhoneAttributesInstance().deviceType.toString();
	}

	public boolean isValidDataNetwork() {
		boolean result = (mPhoneAttr.networkType != NetworkType.UnknownNotConnected);
		return result;
	}
	// *************************

}
